/*
 *------------------------------------------------------------------------------
 * @File      :    ei_mai_venc_define.h
 * @Date      :    2021-4-8
 * @Author    :    lomboswer <lomboswer@lombotech.com>
 * @Brief     :    Media Interface for MADP(Media Development Platform).
 *
 * Copyright (C) 2020-2021, LomboTech Co.Ltd. All rights reserved.
 *------------------------------------------------------------------------------
 */

#ifndef __EI_VENC_DEFINE_H__
#define __EI_VENC_DEFINE_H__

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */

#include "ei_mai_comm_define.h"


/** @addtogroup     ENC */
/** @{ */  /** <!-- [ENC] */

/** max channel count of video encoder*/
#define EI_VENC_MAX_CHN_NUM   8

/** pack number of video encoder*/
#define EI_VENC_PACK_NUM     2

/** max pack count of video encoder frame*/
#define EI_VENC_MAX_FRAME_PACKCOUNT  12

/** limitless count of video encoder frame*/
#define EI_VENC_LIMITLESS_FRAME_COUNT -1

/** max count of VENC channel register call backs*/
#define VENC_CHN_REGISTER_CALLBACK_MAX_COUNT  5

/** max length of VENC head information*/
#define MEDIA_VENC_HEAD_INFO_BUFF_LEN 128

/** max count of screen nail*/
#define MAX_SCREEN_NAIL_COUNT  2

/** Max num of osd region*/
#define EI_VENC_OSD_MAX_NUM   4

// error code for venc
#define EI_ERR_MAI_VENC_HANDLE_ILLEGAL                EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_INVALID_CHNID)
#define EI_ERR_MAI_VENC_ILLEGAL_PARAM                 EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_ILLEGAL_PARAM)
#define EI_ERR_MAI_VENC_EXIST                         EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_EXIST)
#define EI_ERR_MAI_VENC_UNEXIST                       EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_UNEXIST)
#define EI_MAI_ERR_VENC_NOT_SUPPORT                   EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_NOT_SUPPORT)
#define EI_ERR_MAI_VENC_NULL_PTR                      EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_NULL_PTR)
#define EI_ERR_MAI_VENC_NOT_PERM                      EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_NOT_PERM)
#define EI_ERR_MAI_VENC_NOMEM                         EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_NOMEM)
#define EI_ERR_MAI_VENC_NOT_INITED                    EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_SYS_NOTREADY)
#define EI_ERR_MAI_VENC_BUF_EMPTY                     EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_BUF_EMPTY)
#define EI_ERR_MAI_VENC_BUSY                          EI_MADP_DEF_ERR(EI_ID_VENC,MADP_EN_ERR_LEVEL_ERROR,MADP_EN_ERR_BUSY)

typedef struct eiMADP_H264_INTRA_PARAM_S
{
	EI_U32	   intraQP;
	EI_U32     intraPeriod;
	EI_U32     avcIdrPeriod;
	EI_U32	   forcedIdrHeaderEnable;
} EI_MADP_VENC_H264_INTRA_PARAM_S;

typedef struct eiMADP_H265_INTRA_PARAM_S
{
	EI_U32	 intraQP;
	EI_U32	 forcedIdrHeaderEnable;
	EI_U32   intraPeriod;
} EI_MADP_VENC_H265_INTRA_PARAM_S;


/** the attribute of H264 video encoder*/
typedef struct eiMADP_VENC_ATTR_H264_S
{
    EI_U32  u32Profile;                      /**< 0: baseline; 1:Main Profile; 2:High Profile; [0,2]; */
    EI_MADP_VENC_H264_INTRA_PARAM_S stParamRef;
} EI_MADP_VENC_ATTR_H264_S;

/** the attribute of H265 video encoder*/
typedef struct eiMADP_VENC_ATTR_H265_S
{
    EI_U32  u32Profile;                     /**< 0: Main Profile */
    EI_MADP_VENC_H265_INTRA_PARAM_S stParamRef;
} EI_MADP_VENC_ATTR_H265_S;

/** the attribute of JPEG encoder*/
typedef struct eiMADP_VENC_ATTR_JPEG_S
{
    EI_BOOL bEnableDCF;
    EI_U32 u32Qfactor;      /**< [1, 99]*/
} EI_MADP_VENC_ATTR_JPEG_S;

/** the attribute of encoder type*/
typedef struct eiMADP_VENC_TYPE_ATTR_S
{
    EI_MADP_PAYLOAD_TYPE_E  enType;
    EI_MADP_RESOLUTION_S stResolution; /*src*/
    RECT_S stCropRect; /*output*/

    EI_U32 u32BufSize;
    EI_MADP_PIXEL_FORMAT_E enInputFormat;
    union
    {
        EI_MADP_VENC_ATTR_H264_S  stAttrH264e;
        EI_MADP_VENC_ATTR_H265_S  stAttrH265e;
        EI_MADP_VENC_ATTR_JPEG_S  stAttrJpege;
    };

} EI_VENC_TYPE_ATTR_S;

/** the rate control mode*/
typedef enum eiMADP_VENC_RC_MODE_E
{
    EI_MADP_VENC_RC_MODE_CBR,    /**< constant bit rate*/
    EI_MADP_VENC_RC_MODE_VBR,    /**< variable bit rate*/
    EI_MADP_VENC_RC_MODE_FIXQP,    /**< fix qp*/
    EI_MADP_VENC_RC_MODE_BUTT,
} EI_MADP_VENC_RC_MODE_E;

/** the attribute of constant bit rate*/
typedef struct eiMADP_VENC_ATTR_CBR_S
{
    EI_U32    u32Gop;             /**< I frame interval [1, 65536]*/
    EI_U32    u32FrameRate;       /**< frame rate [1, 240]*/
    EI_U32    u32BitRate;         /**< encode bit rate, with Kbps as a unit*/
} EI_MADP_VENC_ATTR_CBR_S;

/** the attribute of variable bit rate*/
typedef struct eiMADP_VENC_ATTR_VBR_S
{
    EI_U32    u32Gop;             /**< I frame interval [1, 65536]*/
    EI_U32    u32FrameRate;       /**< frame rate [1, 240]*/
    EI_U32    u32MaxBitRate;      /**< encode max bit rate, with Kbps as a unit*/
    EI_U32    u32MaxQp;           /**< the max qp [u32MinQp, 51]*/
    EI_U32    u32MinQp;           /**< the min P B qp [0, 51]*/
    EI_U32    u32MinIQp;          /**< min qp for i frame [u32MinQp, u32MaxQp]*/
} EI_MADP_VENC_ATTR_VBR_S;

/** the attribute of rate control*/
typedef struct eiMADP_VENC_RC_ATTR_S
{
    EI_MADP_VENC_RC_MODE_E enRcMode;
    union
    {
        EI_MADP_VENC_ATTR_CBR_S    stAttrCbr;
        EI_MADP_VENC_ATTR_VBR_S    stAttrVbr;
    };
} EI_MADP_VENC_RC_ATTR_S;

/** the attribute of video encode*/
typedef struct eiMADP_VENC_ATTR_S
{
    EI_VENC_TYPE_ATTR_S     stVencPloadTypeAttr;
    EI_MADP_VENC_RC_ATTR_S  stRcAttr;
    EI_U32 u32IsSmartEncodeEnable;
} EI_MADP_VENC_ATTR_S;



/** the NALU type of H264 encode*/
typedef enum eiVENC_DATA_H264E_NALU_TYPE_E
{
    EI_ENC_H264E_NALU_BSLICE = 0,         /**<BSLICE types*/
    EI_ENC_H264E_NALU_PSLICE = 1,         /**<PSLICE types*/
    EI_ENC_H264E_NALU_ISLICE = 2,         /**<ISLICE types*/
    EI_ENC_H264E_NALU_IDRSLICE = 5,       /**<IDRSLICE types*/
    EI_ENC_H264E_NALU_SEI    = 6,         /**<SEI types*/
    EI_ENC_H264E_NALU_SPS    = 7,         /**<SPS types*/
    EI_ENC_H264E_NALU_PPS    = 8,         /**<PPS types*/
    EI_ENC_H264E_INITPACKET ,         /**<INIT PACKET types*/
    EI_ENC_H264E_I_FRAME    ,         /**<I FRAME types*/
    EI_ENC_H264E_P_FRAME    ,         /**<P FRAME types*/
    EI_ENC_H264E_B_FRAME    ,         /**<B FRAME types*/
    EI_ENC_H264E_NALU_BUTT
} EI_VENC_DATA_H264E_NALU_TYPE_E;

/** the NALU type of H265 encode*/
typedef enum eiVENC_H265E_NALU_TYPE_E
{
    EI_ENC_H265E_NALU_BSLICE = 0,          /**<B SLICE types*/
    EI_ENC_H265E_NALU_PSLICE = 1,          /**<P SLICE types*/
    EI_ENC_H265E_NALU_ISLICE = 2,          /**<I SLICE types*/
    EI_ENC_H265E_NALU_IDRSLICE = 19,       /**<IDR SLICE types*/
    EI_ENC_H265E_NALU_VPS    = 32,         /**<VPS types*/
    EI_ENC_H265E_NALU_SPS    = 33,         /**<SPS types*/
    EI_ENC_H265E_NALU_PPS    = 34,         /**<PPS types*/
    EI_ENC_H265E_NALU_SEI    = 39,         /**<SEI types*/
    EI_ENC_H265E_NALU_BUTT
} EI_VENC_DATA_H265E_NALU_TYPE_E;

/** the pack type of JPEG encode*/
typedef enum eiVENC_DATA_JPEG_PACK_TYPE_E
{
    EI_VENC_JPEGE_PACK_ECS = 5,
    EI_VENC_JPEGE_PACK_APP = 6,
    EI_VENC_JPEGE_PACK_VDO = 7,
    EI_VENC_JPEGE_PACK_PIC = 8,
    EI_VENC_JPEGE_PACK_BUTT
}EI_VENC_DATA_JPEGE_PACK_TYPE_E;

/** the pack type of MJPEG4 encode*/
typedef enum eiVENC_DATA_MPEG4E_PACK_TYPE_E
{
    EI_VENC_DATA_MPEG4E_PACK_VOP_P = 1,
    EI_VENC_DATA_MPEG4E_PACK_VOP_I = 5,
    EI_VENC_DATA_MPEG4E_PACK_VOS = 6,
    EI_VENC_DATA_MPEG4E_PACK_VO = 7,
    EI_VENC_DATA_MPEG4E_PACK_VOL = 8,
    EI_VENC_DATA_MPEG4E_PACK_GVOP = 9,
    EI_VENC_DATA_MPEG4E_PACK_BUTT
} EI_VENC_DATA_MPEG4E_PACK_TYPE_E;

/** the slice type*/
typedef enum eiREFSLICE_TYPE_E
{
    EI_REFSLICE_FOR_1X = 1,
    EI_REFSLICE_FOR_2X = 2,
    EI_REFSLICE_FOR_4X = 5,
    EI_REFSLICE_FOR_BUTT
} EI_REFSLICE_TYPE_E;

typedef enum eiREF_TYPE_E
{
    EI_BASE_IDRSLICE = 0,             /**<the Idr frame at Base layer*/
    EI_BASE_PSLICE_REFTOIDR,          /**<the P frame at Base layer, referenced by other frames at Base layer and reference to Idr frame */
    EI_BASE_PSLICE_REFBYBASE,         /**<the P frame at Base layer, referenced by other frames at Base layer*/
    EI_BASE_PSLICE_REFBYENHANCE,      /**<the P frame at Base layer, referenced by other frames at Enhance layer*/
    EI_ENHANCE_PSLICE_REFBYENHANCE,   /**<the P frame at Enhance layer, referenced by other frames at Enhance layer*/
    EI_ENHANCE_PSLICE_NOTFORREF,      /**<the P frame at Enhance layer ,not referenced*/
    EI_ENHANCE_PSLICE_BUTT
} EI_REF_TYPE_E;

/** the data type of video encode*/
typedef struct eiEI_VENC_DATA_TYPE_S
{
    EI_MADP_PAYLOAD_TYPE_E enPayloadType;                    /**< H.264/H.265/JPEG/MJPEG*/
    union
    {
        EI_VENC_DATA_H264E_NALU_TYPE_E    enH264EType;      /**<H264E NALU types*/
        EI_VENC_DATA_H265E_NALU_TYPE_E    enH265EType;      /**<H265E NALU types*/
        EI_VENC_DATA_JPEGE_PACK_TYPE_E    enJPEGEType;      /**<JPEGE PACK types*/
        EI_VENC_DATA_MPEG4E_PACK_TYPE_E   enMPEG4EType;     /**<MJPEGE PACK types*/
    };

} EI_VENC_DATA_TYPE_S;

/** the data pack of video encode*/
typedef struct eiVENC_DATA_PACK_S
{
    EI_U32           u32PhyAddr[EI_VENC_PACK_NUM];      /**< the physics address of stream*/
    EI_U8             *pu8Addr[EI_VENC_PACK_NUM];       /**< the virtual address of stream*/
    EI_U32            au32Len[EI_VENC_PACK_NUM];
    EI_U64            u64PTS;
	EI_BOOL            bFrameEnd;

    EI_VENC_DATA_TYPE_S  stDataType;
    EI_U32   u32Offset;
} EI_VENC_DATA_PACK_S;

/** the stream information of video encode*/
typedef struct eiVENC_STREAM_INFO_S
{
    EI_REFSLICE_TYPE_E enRefSliceType;
    EI_REF_TYPE_E enRefType;
    EI_U32 u32StartQp;
}EI_VENC_STREAM_INFO_S;

/** the data of video encode*/
typedef struct eiVENC_DATA_S
{
    EI_VENC_DATA_PACK_S astPack[EI_VENC_MAX_FRAME_PACKCOUNT];     /**<stream pack attribute*/
    EI_U32              u32PackCount;                             /**<the pack number of one frame stream*/
    EI_U32              u32Seq;                                   /**<the list number of stream*/
    EI_BOOL             bEndOfStream;
    EI_VENC_STREAM_INFO_S stStreamInfo;
    EI_S32              u32UserData;
    EI_HANDLE           hVencHandle;
    EI_VOID             *Priv;
	EI_VOID				*pFrameAddr;
} EI_VENC_DATA_S;

typedef EI_S32 (*PFN_VENC_DataProc)(EI_HANDLE VencHdl, EI_VENC_DATA_S* pVStreamData, EI_VOID *pPrivateData);

typedef struct eiVENC_CALLBACK_S
{
    PFN_VENC_DataProc pfnDataCB;
    EI_VOID *pPrivateData;
} EI_VENC_CALLBACK_S;

/** the head information type of video encode*/
typedef enum eiVENC_HEAD_INFO_TYPE_E
{
    EI_VENC_HEAD_INFO_TYPE_VPS,                         /**<VPS types*/
    EI_VENC_HEAD_INFO_TYPE_PPS,                         /**<PPS types*/
    EI_VENC_HEAD_INFO_TYPE_SPS,                         /**<SPS types*/
    EI_VENC_HEAD_INFO_TYPE_BUTT
} EI_VENC_HEAD_INFO_TYPE_E;

/** the attribute of snap screen nail*/
typedef struct eiSNAP_SCREENNAIL_ATTR_S
{
    EI_U32 u8ScreenNailNum;                                               /**< Default:0, Range:[0,2]; 0: not support screen nail*/
    EI_MADP_RESOLUTION_S astScreenNailResolution[MAX_SCREEN_NAIL_COUNT];   /**< The resolution of screen nail*/
}EI_SNAP_SCREENNAIL_ATTR_S;

/** video encoder extend attribute command*/
typedef enum eiMADP_VENC_CMD_E
{
    EI_MADP_VENC_CMD_GOP_MODE,       /**< EI_MADP_VENC_GOP_ATTR_S*/
    EI_MADP_VENC_CMD_INTRA_REFRESH,  /**< EI_MADP_VENC_PARAM_INTRA_REFRESH_S*/
    EI_MADP_VENC_CMD_FRAME_RATE,     /**< EI_MADP_VENC_FRAME_RATE_S*/
    EI_MADP_VENC_CMD_CreateOsd,
    EI_MADP_VENC_CMD_SetOsd,
    EI_MADP_VENC_CMD_DestroyOsd,
    EI_MADP_VENC_CMD_CreateRect,
    EI_MADP_VENC_CMD_SetRect,
    EI_MADP_VENC_CMD_DestroyRect,
    EI_MADP_VENC_CMD_CreateMasaic,
    EI_MADP_VENC_CMD_DestroyMasaic,
    EI_MADP_VENC_CMD_CreateCover,
    EI_MADP_VENC_CMD_SetCover,
    EI_MADP_VENC_CMD_DestroyCover,
    EI_MADP_VENC_CMD_CreateLine,
    EI_MADP_VENC_CMD_SetLine,
    EI_MADP_VENC_CMD_DestroyLine,
    EI_MADP_VENC_CMD_BUTT
}EI_MADP_VENC_CMD_E;

typedef struct eiVENC_ATTREX_S
{
    EI_HANDLE handle;			/* handle for Osd, rect, cover, 0 ~ 127*/
    union {
        EI_MADP_OSD_ATTR_S stOsdAttr;
        EI_MADP_RECT_ATTR_S stRectAttr;
        EI_MADP_MOSAIC_ATTR_S stMosaicAttr;
        EI_MADP_COVER_ATTR_S stCoverAttr;
        EI_MADP_LINE_ATTR_S stLineAttr;
    };
} VENC_ATTREX_S;

typedef struct eiMADP_VENC_FRAME_RATE_S
{
    EI_S32 s32SrcFrmRate;       /** source frame rate, unit: fps, range: -1 or [1, 240]*/
    EI_S32 s32DstFrmRate;       /** destination frame rate, unit: fps,
                                    range: Jpeg�?1 or [1, s32SrcFrmRate]; H.264/H.265/Mjpeg�?1 or [u32FrameRate, 240]. u32FrameRate see EI_MADP_VENC_RC_ATTR_S*/
} EI_MADP_VENC_FRAME_RATE_S;

typedef enum eiMADP_VENC_GOP_MODE_E
{
    EI_MADP_VENC_GOPMODE_NORMALP = 0,
    EI_MADP_VENC_GOPMODE_DUALP = 1,
//    EI_MADP_VENC_GOPMODE_SMARTP = 2,
    EI_MADP_VENC_GOPMODE_BIPREDB = 3,
    EI_MADP_VENC_GOPMODE_LOWDELAYB = 4,
    EI_MADP_VENC_GOPMODE_BUTT,
}EI_MADP_VENC_GOP_MODE_E;

typedef struct eiMADP_VENC_GOP_NORMALP_S
{
    EI_S32 s32IPQpDelta;    /**< [-10, 30]*/
}EI_MADP_VENC_GOP_NORMALP_S;

typedef struct eiMADP_VENC_GOP_DUALP_S
{
    EI_U32 u32SPInterval;   /**< [0, u32Gop-1]*/
    EI_S32 s32SPQpDelta;    /**< [-10, 30]*/
    EI_S32 s32IPQpDelta;    /**< [-10, 30]*/
} EI_MADP_VENC_GOP_DUALP_S;

//typedef struct eiMADP_VENC_GOP_SMARTP_S
//{
//    EI_U32 u32BgInterval;   /**< [u32Gop, u32Gop*N]*/
//    EI_S32 s32BgQpDelta;    /**< [-10, 30]*/
//    EI_S32 s32ViQpDelta;    /**< [-10, 30]*/
//} EI_MADP_VENC_GOP_SMARTP_S;

typedef struct eiMADP_VENC_GOP_BIPREDB_S
{
    EI_U32 u32BFrmNum;      /**< [1, 3]*/
    EI_S32 s32BQpDelta;     /**< [-10, 30]*/
    EI_S32 s32IPQpDelta;    /**< [-10, 30]*/
} EI_MADP_VENC_GOP_BIPREDB_S;

typedef struct eiMADP_VENC_GOP_ATTR_S
{
    EI_MADP_VENC_GOP_MODE_E enGopMode;
    union
    {
        EI_MADP_VENC_GOP_NORMALP_S stNormalP;
        EI_MADP_VENC_GOP_DUALP_S stDualP;
//        EI_MADP_VENC_GOP_SMARTP_S stSmartP;
        EI_MADP_VENC_GOP_BIPREDB_S stBipredB;
    };
} EI_MADP_VENC_GOP_ATTR_S;

typedef struct eiMADP_VENC_PARAM_INTRA_REFRESH_S
{
    EI_BOOL bRefreshEnable;
    EI_BOOL bISliceEnable;
    EI_U32 u32RefreshLineNum;
    EI_U32 u32ReqIQp;               /**< [0, 51]*/
} EI_MADP_VENC_PARAM_INTRA_REFRESH_S;


typedef struct eiMADP_VENC_CROP_AREA_S
{
	EI_U32  u32OutWidth;
    EI_U32  u32OutHeight;
	RECT_S  Rect;
    EI_U32 u32Quality;
    EI_U32  u32UserData;
}EI_MADP_VENC_CROP_AREA_S;


typedef struct eiMADP_VENC_CROP_ATTR_S
{
	EI_U32  u32AreaNum;
	EI_MADP_VENC_CROP_AREA_S  *pstArea;
}EI_MADP_VENC_CROP_ATTR_S;

/** @}*/  /** <!-- ==== ENC End ====*/
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */

#endif /* End of #ifndef __EI_VENC_DEFINE_H__ */

